package com.example.demo.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.constant.ResponseCode;
import com.example.demo.context.Context;
import com.example.demo.context.CurrentOperator;
import com.example.demo.util.JWTUtil;
import com.example.demo.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
 *@Description token拦截
 *@Author Levi
 *@Date 2019/4/24-9:14
*/
@Slf4j
public class TokenInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    StringRedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return this.checkToken(request, response);
    }

    /**
     * token认证
     * */
    private boolean checkToken(HttpServletRequest request, HttpServletResponse response) {
        //token跨域
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        String token = request.getHeader("token");
        JSONObject result = new JSONObject();
        result.put("timestamp", System.currentTimeMillis());
        result.put("data", "{}");
        if(StringUtil.isEmpty(token)){
            result.put("code", ResponseCode.TOKEN_IS_NULL.getCode());
            result.put("msg", ResponseCode.TOKEN_IS_NULL.getMsg());
            responseMessage(response, result.toJSONString());
            return false;
        }
        CurrentOperator currentOperator = JWTUtil.parseToken(token);
        if (currentOperator == null){
            result.put("code", ResponseCode.TOKEN_PARSE_FAILURE.getCode());
            result.put("msg", ResponseCode.TOKEN_PARSE_FAILURE.getMsg());
            responseMessage(response, result.toJSONString());
            return false;
        }
        String redisToken = redisTemplate.opsForValue().get("token"+currentOperator.getId());
        if(!token.equals(redisToken)){
            result.put("code", ResponseCode.TOKEN_IS_INVALID.getCode());
            result.put("msg", ResponseCode.TOKEN_IS_INVALID.getMsg());
            responseMessage(response, result.toJSONString());
            return false;
        }else{
            Context.currentContext().setCurrentOperator(currentOperator);
            redisTemplate.expire("token"+currentOperator.getId(), 60, TimeUnit.MINUTES);
        }

        return true;
    }

    /**
     * 响应方法
     */
    private void responseMessage(HttpServletResponse response,String message){
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.write(message);
        writer.flush();
        writer.close();
    }
    /**
     * 清空当前线程在Threadlocal的数据，防止内存泄漏
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
        Context.remove();
    }
}
